package goft

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"reflect"
)

type Responder interface {
	RespondTo() gin.HandlerFunc
}

var ResponderList []Responder

func init() {
	ResponderList = []Responder{
		new(StringResponder),
		new(ModelResponder),
		new(ModelsResponder),
		new(ViewResponder),
	}
}

func Convert(handler interface{}) gin.HandlerFunc {
	//获取handler反射值对象
	h_ref := reflect.ValueOf(handler)
	for _, r := range ResponderList {
		//因为是指针类型 所以 .Elem()
		r_ref := reflect.ValueOf(r).Elem()
		//ConvertibleTo判断该类型的值是否可转换为u类型。
		if h_ref.Type().ConvertibleTo(r_ref.Type()) {
			//反射设置值
			r_ref.Set(h_ref)
			//r_ref.Interface() 返回值 并判定类型属于Responder 并调用RespondTo
			return r_ref.Interface().(Responder).RespondTo()
		}
	}
	return nil
}

/**
StringResponder 字符串返回
*/
type StringResponder func(ctx *gin.Context) string

func (r StringResponder) RespondTo() gin.HandlerFunc {
	return func(context *gin.Context) {
		//因为StringResponder 是函数 因此r(context)
		context.String(http.StatusOK, r(context))
	}
}

/**
Model model 返回 detail
*/
type ModelResponder func(ctx *gin.Context) Model

func (r ModelResponder) RespondTo() gin.HandlerFunc {
	return func(context *gin.Context) {
		context.JSON(http.StatusOK, r(context))
	}
}

/**
Models model 切片返回 list
*/
type ModelsResponder func(ctx *gin.Context) Models

func (r ModelsResponder) RespondTo() gin.HandlerFunc {
	return func(context *gin.Context) {
		context.Writer.Header().Set("Context-Type", "application/json")
		context.Writer.WriteString(string(r(context)))
	}
}

/**
ViewResponder html返回
*/
type ViewResponder func(ctx *gin.Context) View

func (r ViewResponder) RespondTo() gin.HandlerFunc {
	return func(context *gin.Context) {
		context.HTML(http.StatusOK, string(r(context))+".html", context.Keys)
	}
}
